package com.xuzhiguang.lightnat.server.core.server.proxy.handler;

import com.xuzhiguang.lightnat.common.manager.ControlChannelManager;
import com.xuzhiguang.lightnat.common.manager.ProxyChannelManager;
import com.xuzhiguang.lightnat.common.message.NatMessage;
import com.xuzhiguang.lightnat.common.message.control.ConnectPush;
import com.xuzhiguang.lightnat.common.util.IdUtil;
import com.xuzhiguang.lightnat.server.core.client.NatClientService;
import com.xuzhiguang.lightnat.server.core.client.NatProxy;
import com.xuzhiguang.lightnat.server.core.server.proxy.util.ProxyUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;

@Slf4j
@ChannelHandler.Sharable
public class ActiveHandler extends ChannelInboundHandlerAdapter {

    private final NatClientService natClientService;

    public ActiveHandler(NatClientService natClientService) {
        this.natClientService = natClientService;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {

        log.debug("proxy channel active. channel:{}", ctx.channel());

        NatProxy natProxy = ProxyUtil.getNatProxy((InetSocketAddress) ctx.channel().localAddress(), natClientService);
        if (ProxyUtil.checkNatProxy(natProxy, ctx.channel())) {

            ctx.channel().config().setAutoRead(false);

            // 生成 sessionId
            long sessionId = IdUtil.nextId();
            ProxyChannelManager.setProxyId(ctx.channel(), natProxy.getId());
            ProxyChannelManager.add(sessionId, ctx.channel());

            // control 发送连接请求给 client 端
            ConnectPush connectPush = new ConnectPush();
            connectPush.setSessionId(sessionId);
            connectPush.setSourceHost(natProxy.getSourceHost());
            connectPush.setSourcePort(natProxy.getSourcePort());
            Channel controlChannel = ControlChannelManager.getChannel(natProxy.getClientId());
            controlChannel.writeAndFlush(new NatMessage(connectPush));
        }

        super.channelActive(ctx);
    }

}
